package com.jsyso.jadmin.common.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jsyso.jsyso.json.jackson.JsonMapper;
import com.jsyso.jsyso.util.JsMap;

/**
 * 树形菜单处理
 * @author janjan, xujian_jason@163.com
 * {
    name: '常用文件夹'
    ,id: 1
    ,alias: 'changyong'
    ,children: [
      {
        name: '所有未读（设置跳转）'
        ,id: 11
        ,href: 'http://www.layui.com/'
        ,alias: 'weidu'
      }, {
        name: '置顶邮件'
        ,id: 12
      }, {
        name: '标签邮件'
        ,id: 13
      }
    ]
  }
 */
public class TreeUtils {

	private List<JsMap> datas;
	private Map<String, List<JsMap>> parentMap;
	
	private int depth = -1;					// 循环深度（-1不限制）
	private String icon;					// 树节点的图标
	private String iconEnd;					// 树节点的结束图标
	private String nbsp;					// 树节点的分隔符
	
	private List<JsMap> treeChainList;		// 用icon/iconEnd/nbsp处理后的链状结构（无childs）
	private List<JsMap> treeList;			// 处理后的数据（有childs）
	
	public static TreeUtils create(List<JsMap> datas) {
		TreeUtils treeUtils = new TreeUtils();
		treeUtils.init(datas);
		return treeUtils;
	}
	
	public void init(List<JsMap> datas) {
		this.datas = datas;
		this.icon = "├─&nbsp;";
		this.iconEnd = "└─&nbsp;";
		this.nbsp = "&nbsp;&nbsp;&nbsp;&nbsp;";
		this.treeChainList = new ArrayList<JsMap>();
		this.parentMap = new HashMap<String, List<JsMap>>();
		pInitParentMap();
	}
	
	public void setIcon(String icon) {
		this.icon = icon;
	}
	
	public void setIconEnd(String iconEnd) {
		this.iconEnd = iconEnd;
	}
	
	public void setNbsp(String nbsp) {
		this.nbsp = nbsp;
	}
	
	public Map<String, List<JsMap>> getParentMap() {
		return parentMap;
	}
	
	private void pInitParentMap() {
		if(this.datas == null || this.datas.isEmpty())
			return ;
		for(JsMap data : datas) {
			String parentId = data.get("parentId", String.class);
			List<JsMap> parentList = parentMap.get(parentId);
			if(parentList == null) {
				parentList = new ArrayList<JsMap>();
				parentMap.put(parentId, parentList);
			}
			parentList.add(data);
		}
	}
	
	private void pGetTree(List<JsMap> parentList, int level) {
		if(level < 1) level = 1;
		for(int i=0; parentList != null 
				&& i<parentList.size(); ++i) {
			String showIcon = i == (parentList.size() - 1) ? iconEnd : icon;
			JsMap t = parentList.get(i);
			// 计算空格
			StringBuilder nbspBuilder = new StringBuilder("");
			for(int j=1; j<level; ++j) nbspBuilder.append(nbsp);
			if(level > 1) nbspBuilder.append(showIcon);
			t.set("level", level)
			.set("alias", nbspBuilder.append(t.get("name", String.class)).toString());
			treeChainList.add(t);
			// 获取当前子项
			List<JsMap> childList = parentMap.get(t.get("id", String.class));
			if(childList != null && !childList.isEmpty()) {
				t.set("children", childList);
				// 计算下一个菜单
				if(this.depth < 0 || level < this.depth)
					pGetTree(childList, level + 1);
			}
		}
	}
	
	public List<JsMap> getTree(int depth, boolean chainTreeList) {
		this.depth = depth;
		treeList = parentMap.get("0");
		pGetTree(treeList, 1);
		return chainTreeList ? treeChainList : treeList;
	}
	
	public List<JsMap> getTree() {
		return getTree(-1, false);
	}
	
	public List<JsMap> getTree(int depth) {
		return getTree(depth, false);
	}
	
	public List<JsMap> getChainTree() {
		return getTree(-1, true);
	}
	
	public static void main(String[] args) {
		 /*
	     * array(
	     *      1 => array('id'=>'1','parentId'=>0,'name'=>'一级栏目一'),
	     *      2 => array('id'=>'2','parentId'=>0,'name'=>'一级栏目二'),
	     *      3 => array('id'=>'3','parentId'=>1,'name'=>'二级栏目一'),
	     *      4 => array('id'=>'4','parentId'=>1,'name'=>'二级栏目二'),
	     *      5 => array('id'=>'5','parentId'=>2,'name'=>'二级栏目三'),
	     *      6 => array('id'=>'6','parentId'=>3,'name'=>'三级栏目一'),
	     *      7 => array('id'=>'7','parentId'=>3,'name'=>'三级栏目二')
	     *      )
	     */
		int id = 1;
		List<JsMap> list = new ArrayList<JsMap>();
		list.add(JsMap.create("id", id++).set("parentId", 0).set("name", "一级栏目一"));
		list.add(JsMap.create("id", id++).set("parentId", 0).set("name", "一级栏目二"));
		list.add(JsMap.create("id", id++).set("parentId", 1).set("name", "二级栏目一"));
		list.add(JsMap.create("id", id++).set("parentId", 1).set("name", "二级栏目二"));
		list.add(JsMap.create("id", id++).set("parentId", 2).set("name", "二级栏目三"));
		list.add(JsMap.create("id", id++).set("parentId", 3).set("name", "三级栏目一"));
		list.add(JsMap.create("id", id++).set("parentId", 3).set("name", "三级栏目二"));
		List<JsMap> treeList = TreeUtils.create(list).getTree(2);
		System.out.println(JsonMapper.getInstance().toJson(treeList));
	}
	
}
